#include<stdio.h>
#include<string.h>
/*设计魔方阵(只考虑奇数阶)

规律：
一般解法：
	将1放在第一行中间一列
	从2开始到为止，每个数字的排放规律为：
	每一个数字排放的行比前一个数字的行数减1，每个数字排放的列比前一个数字的列数加1
	行的特殊情况：如果前一个数字的行数为1，那么该数字排在第n行
	列的特殊情况：如果前一个数字的列数为n，那么该数字排在第1列
	其他情况：如果按照上面规律确定的位置上已经有数字，则把要排的数字放在上一个数字的下面。
	
	17	24	1	8	15
	23	5	7	14	16
	4	6	13	20	22
	10	12	19	21	3
	11	18	25	2	9

*/

void odd_number(int n,int a[100][100])
{
	int i;
	int row,column,row_0,column_0;//row为行，column为列，row和column记录行和列坐标
	row=0,column=(n+1)/2-1;//初始化，行列坐标

	//将1放在第一行中间一列
	a[row][column]=1;

	/*
	从2开始到为止，每个数字的排放规律为：
	每一个数字排放的行比前一个数字的行数减1，每个数字排放的列比前一个数字的列数加1
	行的特殊情况：如果前一个数字的行数为1，那么该数字排在第n行
	列的特殊情况：如果前一个数字的列数为n，那么该数字排在第1列
	其他情况：如果按照上面规律确定的位置上已经有数字，则把要排的数字放在上一个数字的下面。
	*/
	for(i=2;i<n*n;i++)
	{
		row_0=row,column_0=column;//记录上一次循环的行，列坐标
		if(row==0&&column==n-1)//第1行第n列的情况
		{
			row=n-1;//该数字排在第n行
			column=0;//该数字排在第1列
		}
		else if(row==0)//第一行非第n列
		{
			row=n-1;//该数字排在第n行
			column++;//列坐标加1
		}
		else if(column==n-1)//第n列非第一行
		{
			column=0;//该数字排在第1列
			row--;//行坐标减1
		}
		//普通情况，每一个数字排放的行比前一个数字的行数减1，每个数字排放的列比前一个数字的列数加1
		else
		{
			row--;
			column++;
		}
		//其他情况,如果按照上面规律确定的位置上已经有数字，则把要排的数字放在上一个数字的下面。
		if(a[row][column]!=0)
		{
			row=row_0+1;
			column=column_0;
		}
		a[row][column]=i;//赋值
	}
}

int main()
{
	int n;
	int a[100][100]={0};
	printf("请输入你想要输出的奇数魔方阵阶数（请输入奇数): \n" );
	scanf( "%d" ,&n) ;
	
	odd_number(n,a);

	//输出二维数组
	int i,j;	
	int cnt=0;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			printf("%4d",a[i][j]);
			cnt++;
			if(cnt%n==0) putchar('\n');
		}
	}
	
	return 0;
}
